<?php 

class Zen_Cache_Page {
	
	private $_started = false;
	
	private $cache = false;
	
	private $clean = false;
	
	private $path = '';
	
	private $file = '';
	
	private $_list_file = '/site/settings/cache_list.txt';
	
	public function __construct($params) {
		if ($params->cache->on == true)
			$this->cache = true;
		if ($params->cache->clean->on == true)
			$this->clean = true;
		$this->path = ROOT_PATH."/site/cache/pages";
		if(!file_exists($this->path)){
			mkdir($this->path,0777,true);
		}
	}

	public function start() { 
		if (($this->cache == false)||($_SERVER['REQUEST_METHOD']!='GET')) 
			return ;
		$url = $_SERVER['REQUEST_URI'];
		if (! $this->_checkUrl($url) ) 
			return;
		$url = $this->_prepareUrl($url);
		$file = $this->path . $url;
		if (file_exists($file)) {
			echo file_get_contents($file);
			exit();
		}
		$this->file = $file;
		$this->_started = true;
		ob_start();
	}
	
	public function end() {
		if (! $this->_started) return ;
		$file = $this->file;
		$dir = preg_replace('/\w+\.\w+$/', '', $file);
		if (! file_exists($dir)) {
			mkdir($dir, 0777, true);
		}
		$handle = fopen($file, "w+");
		$text = ob_get_contents();
		$text = $this->_clean($text);
		
		fwrite($handle, $text);
		fclose($handle);
		ob_end_flush();
	}
	
	private function _checkUrl($url) {
		// добавляем принудительно в конец url slash
		$url = preg_replace ( '/\/$/', '', $url );
		$url = $url . '/';
		$list = $this->_getUrlsToCache();
		foreach ($list as $item) {
			// если в шаблоне символ обобщения * 
			if (! preg_match ( '/\\*$/', $item )) {
				// добавляем принудительно в конец url slash
				$item = preg_replace ( '/\/$/', '', $item );
				$item = $item . "/";
			}
			// заменяем slash на экранированный slash
			$item = preg_replace ( '/\//', '\/', $item );
			// заменяем символ обобщения * на эквивалентный в regexp
			$item = preg_replace ( '/\*/', '.*', $item );
			
			if (preg_match ( '/^' . $item . '$/', $url )) {
				return true;
			}
		}
	}
	
	private function _getUrlsToCache() {
		$list_file = ROOT_PATH . $this->_list_file;
		if (! file_exists($list_file)) return array();
		$plain_text = file_get_contents($list_file);
		$plain_text = $this->_clean($plain_text);
		$list = explode ( ',', $plain_text );
		return $list;
	}
	
	private function _prepareUrl($url) {
		if ($url == '/') {
			$url = '/index.html';
		} else {
			preg_match('/\S+\.(\S+)$/', $url, $out);
			if (!isset($out[1])) {
				$this->file = preg_replace('/\\/$/', '', $this->file) . '/index.html';
			}
		}
		return $url;
	}
	
	private function _clean($text) {
		$text = preg_replace('/<!--clean-cache-start-->.*<!--clean-cache-end-->/Uis', '', $text);
		if (! $this->clean ) 
			return $text;
		//Удаление комментариев
	    $text = preg_replace('/<!--.*-->/Uis', '', $text);
	    $text = str_replace(array(
			"\r\n", 
			"\r", 
			"\n", 
			"\t"), '', $text);
	    $text = preg_replace('/\040+/ui',' ', $text);
	    $text = str_replace(array("> <"), '><', $text);
		return text;
	} 
	
	private function recursive_remove_directory($directory, $empty=FALSE) {
		// if the path has a slash at the end we remove it here
		if(substr($directory,-1) == '/') {
			$directory = substr($directory,0,-1);
		}
		// if the path is not valid or is not a directory ...
		if(!file_exists($directory) || !is_dir($directory))	{
			// ... we return false and exit the function
			return FALSE;
		// ... if the path is not readable
		}elseif(!is_readable($directory)) {
			// ... we return false and exit the function
			return FALSE;
		// ... else if the path is readable
		}else{
			// we open the directory
			$handle = opendir($directory);
			// and scan through the items inside
			while (FALSE !== ($item = readdir($handle))) {
				// if the filepointer is not the current directory
				// or the parent directory
				if($item != '.' && $item != '..') {
					// we build the new path to delete
					$path = $directory.'/'.$item;
					// if the new path is a directory
					if(is_dir($path)) {
						// we call this function with the new path
						$this->recursive_remove_directory($path);
	
					// if the new path is a file
					}else{
						// we remove the file
						unlink($path);
					}
				}
			}
			// close the directory
			closedir($handle);
			// if the option to empty is not set to true
			if($empty == FALSE)	{
				// try to delete the now empty directory
				if(!rmdir($directory)){
					// return false if not possible
					return FALSE;
				}
			}
			// return success
			return TRUE;
		}
	}
}